//           Copyright Daniel Goertzen 2007.
//  Distributed under the Boost Software License, Version 1.0.
//     (See accompanying file LICENSE_1_0.txt or copy at
//           http://www.boost.org/LICENSE_1_0.txt)

#ifndef EIPP_TYPES_H
#define EIPP_TYPES_H

#include <stdint.h>
#include <limits.h>
#include <values.h>

#include <string>
#include <deque>
#include <vector>
#include <sstream>
#include <boost/shared_ptr.hpp>
#include <boost/typeof/typeof.hpp>


namespace eipp
{
	using namespace boost;
	using namespace std;

//	class et;
	

// 	typedef std::string string_t;
	class string_t: public std::string
	{
	public:
		string_t(const std::string &s):std::string(s){}
		string_t(const char *s):std::string(s){}
		string_t():std::string(){}
	};

//	typedef atom_t atom;
	class atom_t: public std::string
	{
	public:
		atom_t(const std::string &s):std::string(s){}
		atom_t(const char *s):std::string(s){}
		atom_t():std::string(){}
	};

	class sequence_t: public std::deque<et>
	{};

	class list_t: public sequence_t{};
	class tuple_t: public sequence_t{};
	class binary_t: public std::vector<unsigned char>{};

	ostream &operator<<(ostream &ss,const list_t &d)
	{
		ss << '[';
		BOOST_AUTO(i,d.begin());
		if(i!=d.end())
		{
			while(1)
			{
				ss << (*i);
				i++;
				if(i==d.end()) break;
				ss << ',';
			}
		}
		ss << ']';
		return ss;
	}

	ostream &operator<<(ostream &ss,const tuple_t &d)
	{
		ss << '{';
		BOOST_AUTO(i,d.begin());
		if(i!=d.end())
		{
			while(1)
			{
				ss << (*i);
				i++;
				if(i==d.end()) break;
				ss << ',';
			}
		}
		ss << '}';
		return ss;
	}

	ostream &operator<<(ostream &ss,const binary_t &d)
	{
		ss << "<<";
		BOOST_AUTO(i,d.begin());
		if(i!=d.end())
		{
			while(1)
			{
				ss << (*i);
				i++;
				if(i==d.end()) break;
				ss << ',';
			}
		}
		ss << ">>";
		return ss;
	}



//	typedef std::vector<char> binary_t;

// 	typedef shared_ptr<list_t> splist_t;
// 	typedef shared_ptr<tuple_t> sptuple_t;
// 	typedef shared_ptr<binary_t> spbinary_t;

// 	typedef shared_ptr<erlang_ref> sperlang_ref;
// 	typedef shared_ptr<erlang_port> sperlang_port;
// 	typedef shared_ptr<erlang_pid> sperlang_pid;
// 	typedef shared_ptr<erlang_trace> sperlang_trace;

// wrapper for erlang_fun that cleans up after itself
// 	class safe_erlang_fun: public erlang_fun
// 	{
// 	public:
// 		~safe_erlang_fun(){ free_fun(this);}
// 	};

// 	typedef shared_ptr<safe_erlang_fun> spsafe_erlang_fun;

}//namespace

#endif
